package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersConfirmDTO;
import com.sky.dto.OrdersPageQueryDTO;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.*;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.*;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.utils.WeChatPayUtil;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {
  
  @Autowired
  private OrderMapper orderMapper;
  @Autowired
  private OrderDetailMapper orderDetailMapper;
  @Autowired
  private AddressBookMapper addressBookMapper;
  @Autowired
  private ShoppingCartMapper shoppingCartMapper;
  @Autowired
  private UserMapper userMapper;
  @Autowired
  private WeChatPayUtil weChatPayUtil;
  @Autowired
  private WebSocketServer webSocketServer;
  
  /**
   * 用户下单
   * @param ordersSubmitDTO
   */
  @Override
  @Transactional
  public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
    // 1.处理各种业务异常（地址簿或购物车为空的情况）
    // 1.1判断地址簿是否为空
    AddressBook addressBook = addressBookMapper.findById(ordersSubmitDTO.getAddressBookId());
    if(addressBook == null) {
      throw new OrderBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
    }
    // 1.2判断购物车是否为空
    ShoppingCart shoppingCart = ShoppingCart.builder().userId(BaseContext.getCurrentId()).build();
    List<ShoppingCart> carts = shoppingCartMapper.list(shoppingCart);
    if (carts == null || carts.isEmpty()) {
      throw new OrderBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
    }
    // 2.向订单表插入1条数据
    Orders orders = new Orders();
    BeanUtils.copyProperties(ordersSubmitDTO, orders);
    orders.setOrderTime(LocalDateTime.now());
    orders.setPayStatus(Orders.UN_PAID);
    orders.setStatus(Orders.PENDING_PAYMENT);
    orders.setNumber(String.valueOf(System.currentTimeMillis()));
    orders.setPhone(addressBook.getPhone());
    orders.setConsignee(addressBook.getConsignee());
    orders.setUserId(BaseContext.getCurrentId());
    orders.setAddress(addressBook.getDetail());
    orderMapper.insert(orders);
    
    // 3.向订单明细表插入n条数据
    for (ShoppingCart cart : carts) {
      OrderDetail orderDetail = new OrderDetail(); // 订单明细
      BeanUtils.copyProperties(cart, orderDetail);
      orderDetail.setOrderId(orders.getId());
      orderDetailMapper.insert(orderDetail);
    }
    
    // 4.清空用户购物车
    shoppingCartMapper.deleteByUserId(BaseContext.getCurrentId());
    
    // 5.封装vo返回结果
    return OrderSubmitVO.builder()
        .id(orders.getId())
        .orderNumber(orders.getNumber())
        .orderAmount(orders.getAmount())
        .orderTime(orders.getOrderTime())
        .build();
  }
  
  /**
   * 处理订单支付请求。
   * @param ordersPaymentDTO 订单支付数据传输对象，包含订单号和付款方式
   * @return OrderPaymentVO 订单支付视图对象，包含随机字符串、签名、时间戳、签名算法及预支付交易会话标识
   */
  @Override
  public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
    // 根据userId查询用户
    User user = userMapper.findUserByUserId(BaseContext.getCurrentId());
    
    // 调用微信支付接口，生成预支付交易单
    // JSONObject jsonObject = weChatPayUtil.pay(
    //     ordersPaymentDTO.getOrderNumber(), // 商户订单号
    //     new BigDecimal(100), // 订单支付金额
    //     "苍穹外卖订单", // 商品描述
    //     user.getOpenid() // 微信用户的openid
    // );
    
    JSONObject jsonObject = new JSONObject();
    
    if(jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
      throw new OrderBusinessException("该订单已支付~");
    }
    
    // json转成java对象
    OrderPaymentVO orderPaymentVO = jsonObject.toJavaObject(OrderPaymentVO.class);
    orderPaymentVO.setPackageStr(jsonObject.getString("package"));
    return orderPaymentVO;
  }
  
  /**
   * 标记支付成功，并更新相关订单状态。
   * @param outTradeNo 第三方支付平台返回的交易号
   */
  @Override
  public void paySuccess(String outTradeNo) {
    Long userId = BaseContext.getCurrentId();
    // 根据订单号查询当前用户订单
    Orders ordersDB = orderMapper.getByNumberAndUserId(outTradeNo, userId);
    // 根据订单id 更新订单状态等
    Orders orders = Orders.builder()
        .id(ordersDB.getId())
        .status(Orders.TO_BE_CONFIRMED)
        .payStatus(Orders.PAID)
        .checkoutTime(LocalDateTime.now())
        .build();
    
    orderMapper.update(orders);
    
    // 通过WebSocket向客户端推送消息 type orderId content
    Map<String, Object> map = new HashMap<>();
    map.put("type", 1); // 1 来单提醒 2 客户催单
    map.put("orderId", ordersDB.getId());
    map.put("content", "订单号："+outTradeNo);
    
    String jsonString = JSON.toJSONString(map);
    webSocketServer.sendToAllClient(jsonString);
    
  }
  
  
  /**
   * 搜索订单信息
   * @param queryDTO 查询参数，包含分页信息、订单号、电话、状态、开始时间、结束时间和用户ID
   * @return PageResult 包含总记录数和当前页数据集合的分页结果对象
   */
  @Override
  public PageResult conditionSearch(OrdersPageQueryDTO queryDTO) {
    PageHelper.startPage(queryDTO.getPage(), queryDTO.getPageSize());
    Page<Orders> page = orderMapper.pageQuery(queryDTO);
    
    // 部分订单状态，需要额外返回订单菜品信息，将Orders转化为OrderVO
    List<OrderVO> orderVOList = getOrderVOList(page);
    return new PageResult(page.getTotal(), orderVOList);
  }
  
  /**
   * 将 Orders 页面转换为 OrderVO 对象列表，用订单菜肴信息丰富每个对象.
   */
  private List<OrderVO> getOrderVOList(Page<Orders> page) {
    // 需要返回订单菜品信息，自定义OrderVO响应结果
    List<OrderVO> orderVOList = new ArrayList<>();
    
    List<Orders> ordersList = page.getResult();
    if(!CollectionUtils.isEmpty(ordersList)) {
      for (Orders orders : ordersList) {
        // 将共同字段复制到OrderVO
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        String orderDishes = getOrderDishesStr(orders);
        
        // 将订单菜品信息封装到orderVO中，并添加到orderVOList
        orderVO.setOrderDishes(orderDishes);
        orderVOList.add(orderVO);
      }
    }
    return orderVOList;
  }
  
  /**
   * 根据订单id获取菜品信息字符串
   */
  private String getOrderDishesStr(Orders orders) {
    // 查询订单菜品详情信息（订单中的菜品和数量）
    List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(orders.getId());
    
    // 将每一条订单菜品信息拼接为字符串（格式：宫保鸡丁*3；）
    List<String> orderDishList = orderDetailList.stream().map(x -> {
      String orderDish = x.getName() + "*" + x.getNumber() + ";";
      return orderDish;
    }).collect(Collectors.toList());
    
    // 将该订单对应的所有菜品信息拼接在一起
    return String.join("", orderDishList);
  }
  
  /**
   * 统计个订单状态数量
   * @return
   */
  @Override
  public OrderStatisticsVO statistics() {
    return orderMapper.statistics();
  }
  
  
  /**
   * 用户端订单分页查询
   */
  @Override
  public PageResult pageQuery(OrdersPageQueryDTO queryDTO) {
    PageHelper.startPage(queryDTO.getPage(), queryDTO.getPageSize());
    queryDTO.setUserId(BaseContext.getCurrentId());
    
    // 分页条件查询
    Page<Orders> page = orderMapper.pageQuery(queryDTO);
    
    List<OrderVO> list = new ArrayList();
    
    // 查询出订单明细，并封装入OrderVO进行响应
    if (page != null && page.getTotal() > 0) {
      for (Orders orders : page) {
        Long orderId = orders.getId();// 订单id
        
        // 查询订单明细
        List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderId);
        
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        orderVO.setOrderDetailList(orderDetails);
        
        list.add(orderVO);
      }
    }
    return new PageResult(page.getTotal(), list);
  }
  
  /**
   *
   * @param id
   * @return
   */
  @Override
  public OrderVO details(Long id) {
    // 根据id查询订单
    Orders orders = orderMapper.getById(id);
    
    // 查询该订单对应的菜品/套餐明细
    List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(orders.getId());
    
    // 将该订单及其详情封装到OrderVO并返回
    OrderVO orderVO = new OrderVO();
    BeanUtils.copyProperties(orders, orderVO);
    orderVO.setOrderDetailList(orderDetailList);
    
    return orderVO;
  }
  
  /**
   * 接单
   * @param ordersConfirmDTO
   */
  @Override
  public void confirm(OrdersConfirmDTO ordersConfirmDTO) {
    Orders orders = Orders.builder()
        .id(ordersConfirmDTO.getId())
        .status(Orders.CONFIRMED)
        .build();
    
    orderMapper.update(orders);
    
  }
  
  /**
   * 派送
   * @param id
   */
  @Override
  public void delivery(Long id) {
    // 根据id查询订单
    Orders ordersDB = orderMapper.getById(id);
    
    // 校验订单是否存在，并且状态为3
    if (ordersDB == null || !ordersDB.getStatus().equals(Orders.CONFIRMED)) {
      throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
    }
    
    Orders orders = Orders.builder()
        .id(ordersDB.getId())
        .status(Orders.DELIVERY_IN_PROGRESS) // 更新订单状态,状态转为派送中
        .build();
    
    orderMapper.update(orders);
  }
  
  /**
   * 完成订单
   * @param id
   */
  @Override
  public void complete(Long id) {
    // 根据id查询订单
    Orders ordersDB = orderMapper.getById(id);
    
    // 校验订单是否存在，并且状态为4
    if (ordersDB == null || !ordersDB.getStatus().equals(Orders.DELIVERY_IN_PROGRESS)) {
      throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
    }
    
    Orders orders = new Orders();
    orders.setId(ordersDB.getId());
    orders.setStatus(Orders.COMPLETED);
    orders.setDeliveryTime(LocalDateTime.now());
    
    orderMapper.update(orders);
  
  }
  
  /**
   * 用户取消订单
   * @param id
   */
  @Override
  public void userCancelById(Long id) throws Exception {
    // 根据id查询订单
    Orders ordersDB = orderMapper.getById(id);
    // 校验订单是否存在
    if (ordersDB == null) {
      throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
    }
    //订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消
    if (ordersDB.getStatus() > 2) {
      throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
    }
    Orders orders = new Orders();
    orders.setId(ordersDB.getId());
    
    // 订单处于待接单状态下取消，需要进行退款
    if (ordersDB.getStatus().equals(Orders.TO_BE_CONFIRMED)) {
      //调用微信支付退款接口
      weChatPayUtil.refund(
          ordersDB.getNumber(), //商户订单号
          ordersDB.getNumber(), //商户退款单号
          new BigDecimal(0.01),//退款金额，单位 元
          new BigDecimal(0.01));//原订单金额
      
      //支付状态修改为 退款
      orders.setPayStatus(Orders.REFUND);
    }
    
    // 更新订单状态、取消原因、取消时间
    orders.setStatus(Orders.CANCELLED);
    orders.setCancelReason("用户取消");
    orders.setCancelTime(LocalDateTime.now());
    orderMapper.update(orders);
  }
  
  /**
   * 再来一单
   * @param id  订单id
   */
  @Override
  public void repetition(Long id) {
    // 查询当前用户id
    Long userId = BaseContext.getCurrentId();
    
    // 根据订单id查询当前订单详情
    List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(id);
    
    // 将订单详情对象转换为购物车对象
    List<ShoppingCart> shoppingCartList = orderDetailList.stream().map(x -> {
      ShoppingCart shoppingCart = new ShoppingCart();
      
      // 将原订单详情里面的菜品信息重新复制到购物车对象中
      BeanUtils.copyProperties(x, shoppingCart, "id");
      shoppingCart.setUserId(userId);
      shoppingCart.setCreateTime(LocalDateTime.now());
      
      return shoppingCart;
    }).collect(Collectors.toList());
    
    // 将购物车对象批量添加到数据库
    shoppingCartMapper.insertBatch(shoppingCartList);
  }
}
